import React, { useReducer } from "react"

interface FormField {
    value: string
    error: string
}

interface FormState {
    username: FormField
    password: FormField
    confirmPassword: FormField
}

type FieldName = 'username' | 'password' | 'confirmPassword'

type FormAction =
    | { type: 'UPDATE_FIELD', payload: { field: FieldName, value: string } }
    | { type: 'VALIDATE_FORM' }

const initialState: FormState = {
    username: { value: '', error: '' },
    password: { value: '', error: '' },
    confirmPassword: { value: '', error: '' }
}

const formReducer = (state: FormState, action: FormAction): FormState => {
    switch (action.type) {
        case 'UPDATE_FIELD':
            let newFieldState: FormField
            switch (action.payload.field) {
                case 'username':
                    newFieldState = { value: action.payload.value, error: action.payload.value.length < 3 ? 'Username must be at least 3 characters' : '' }
                    break;
                case 'password':
                    newFieldState = { value: action.payload.value, error: action.payload.value.length < 6 ? 'Password must be at least 6 characters' : '' };
                    break
                case 'confirmPassword':
                    newFieldState = { value: action.payload.value, error: state.password.value !== action.payload.value ? 'Passwords do not match' : '' };
                    break

                default:
                    newFieldState = { value: '', error: '' }
                    break;
            }
            return {
                ...state,
                [action.payload.field]: newFieldState
            };

        case 'VALIDATE_FORM':
            // const hasErrors = Object.values(state).some(field => field.error !== '')
            // if (!hasErrors) {
            //     return state
            // }
            // alert('Something wrong!')
            const errors = Object.values(state).reduce((acc, field) => {
                if (field.error) {
                    acc.push(field.error)
                }
                return acc
            }, [])
            if (errors.length > 0) {
                // return {
                //     ...state,
                //     error
                // }
                alert(errors.join('; '))
            }
            return state
        default:
            return state
    }
}

export default function RegisterApp() {
    const [state, dispatch] = useReducer(formReducer, initialState)

    const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault()
        dispatch({ type: 'VALIDATE_FORM' })

    }
    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        e.preventDefault()
        dispatch({ type: 'UPDATE_FIELD', payload: { field: e.target.name as FieldName, value: e.target.value } })
    }

    const spanStyle: React.CSSProperties = {
        color: 'red',
        fontSize: '12px',
    }

    const formStyle: React.CSSProperties = {
        padding: '15px',
        borderStyle: 'solid', // 设置边框样式为实线，这是关键，之前只写 border 是不对的
        borderWidth: '1px',
        borderColor: '#999',
        borderRadius: '5px'
    }

    return (
        <form onSubmit={handleSubmit} style={formStyle}>
            <h5>注册表格</h5>
            <label>UserName:
                <input type="text" name="username" value={state.username.value} onChange={handleInputChange} />
                {state.username.error && <span style={spanStyle}>{state.username.error}</span>}
            </label>
            <br />
            <label>
                Password:
                <input type="text" name="password" value={state.password.value} onChange={handleInputChange} />
                {state.password.error && <span style={spanStyle}>{state.password.error}</span>}
            </label>
            <br />
            <label>
                Confirm Password:
                <input type="text" name="confirmPassword" value={state.confirmPassword.value} onChange={handleInputChange} />
                {state.confirmPassword.error && <span style={spanStyle}>{state.confirmPassword.error}</span>}
            </label>
            <br />
            <button type="submit">Submit</button>
        </form>
    )
}